1. Field of the Invention
The present invention relates to computer instruction code. More specifically, the present invention relates to a method and an apparatus for removing class initialization barriers from shared compiled methods.
2. Related Art
Computer programs written in languages such as JAVA™ are compiled into a platform-independent code, which is executed on a virtual machine, such as a JAVA VIRTUAL MACHINE (JVM). A program that has been compiled into a platform-independent code has the advantage that it can execute on any virtual machine that supports the platform-independent code regardless of what type of underlying central processing unit and native code are used to implement the virtual machine. The terms JAVA, JVM, and JAVA VIRTUAL MACHINE are trademarks or registered trademarks of SUN Microsystems, Inc. of Palo Alto, Calif.
A virtual machine typically includes an interpreter, which interprets the platform-independent code into native code to perform the desired operations. Interpreting the platform-independent code is an inherently slow operation. Therefore, many virtual machine implementations also include a dynamic compiler, which dynamically compiles the platform-independent code at runtime into the native code for the machine being used to host the virtual machine. Compiling the platform-independent code into the native code for the host machine can reduce the execution time of the program and, therefore, increase throughput.
Virtual machines for object-oriented programming languages with dynamic class loading typically load the code of a class when a program resolves a symbolic reference to that class for the first time. The class needs to be initialized subsequently when the program uses it for the first time. Loading and initialization of a class are two separate events. Initialization of a class may never take place even though the class has been loaded before. In the case of the Java programming language, the initialization of a class includes executing the class's static initializer, which brings the class's variables (also known as the static variables) to a well-defined initialized state. A virtual machine implementation may choose to set a class to the initialized state upon its loading when no action is required to initialize that class. For instance, in the Java programming language, no action is required to initialize a class when this class has no declared static initialization sequence, and either no non-final static variables, or non-final static variables that are all declared to be set to a default value. In this case, a virtual machine implementation can benefit from setting such initialization-less classes to the initialized state upon class loading.
A class initialization barrier is a sequence of native instructions that calls the virtual machine's runtime to initialize a class if the class is not already initialized. Class initialization barriers are included in the implementation of those platform-independent instructions that may result in the very first use of a class (in the case of the Java programming language, there are four such instructions: getstatic, putstatic, invokestatic, new). The implementation of a platform-independent instruction can come in two flavors: (i) as a sequence of instructions that is part of the implementation of an interpreter of platform-independent instructions, (ii) or as a sequence of instructions generated by a dynamic compiler from platform-independent instructions.
Dynamic compilers have two ways to eliminate class initialization barriers. Simple static analysis (complex static analyses are most of the time out of question because of their cost, which is unacceptable for a runtime compiler), and code patching.
Dynamic compilers take advantage of their knowledge about the current runtime state of an executed program to eliminate class initialization barriers at compile-time: typically, class initialization barriers are not emitted for classes that have been initialized. For those cases where a class hasn't been initialized by the time the compilation takes place, self-rewriting code is generated instead in order to eliminate the class initialization barriers at execution time.
In order to save processing and memory, a multitasking virtual machine (MVM) aims at sharing as much of the runtime representation of a class as possible between tasks. Targets for sharing include the platform-independent code, the meta-data describing the class, and the native code produced by the dynamic compiler. Sharing the latter across sequential or concurrent execution of a program offers many advantages: it factors out the costs of runtime compilations, it eliminates the need for interpretation since compiled code is immediately available, and it reduces the space overhead of compiled methods when platform-independent programs are run simultaneously.
Unfortunately, sharing compiled code invalidates current class initialization barrier removal techniques because of dynamic loading: classes may be loaded in different order by different programs, or even by multiple executions of the same program. Therefore, an assumption that is correct for one execution (e.g., class A is initialized) may be incorrect in another. Because of this, class initialization barriers can be omitted only if the order of class initialization is guaranteed to be always the same for all possible executions of any programs using these classes.
Class initialization barrier elimination is also important to enable some optimization techniques, such as, the inlining of static methods. Inlining can bring significant performance gains, especially for methods that are frequently used. Most dynamic compilers do not attempt to inline a method if its class hasn't been initialized by the time the compilation takes place. If class initialization barriers can be eliminated for a particular static method call site, then it is possible to inline the method at this call site (provided that other inlining conditions apply as well).
What is needed is a method and an apparatus, which allows removal of class initialization barriers from shared compiled methods that do not exhibit the problems defined above.